<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>WebRTC 调试页面</title>
    <style>
        body { font-family: Arial; padding: 20px; }
        label, input, textarea, button { display: block; width: 100%; margin-top: 10px; }
        video {
            width: 100%;
            max-width: 800px;
            margin-top: 20px;
            background-color: black;
        }
    </style>
</head>
<body>
<h2>WebRTC 拉流测试</h2>

<!-- 共用输入框 -->
<div>
    <label for="app">应用名称 (app)</label>
    <input type="text" id="app" value="live">
</div>

<div>
    <label for="stream">流标识 (stream)</label>
    <input type="text" id="stream" value="camera_001">
</div>

<div>
    <label for="type">SDP 类型 (type): play / push / echo</label>
    <input type="text" id="type" value="play">
</div>

<div>
    <label for="pcSdp">PC SDP 内容 (pcSdp)</label>
    <textarea id="pcSdp"></textarea>
</div>


<!-- 左右布局容器 -->
<div style="display: flex; gap: 20px; margin-top: 30px;">
    <!-- 实时播放区域 -->
    <div style="flex: 2;">
        <h3>实时播放</h3>
        <div>
            <button onclick="generateOffer()">生成 Offer 并播放</button>
            <button onclick="stopPlayback()">关闭播放</button>
            <button onclick="testBackend()">测试后端接口</button>
        </div>
        <video id="videoElement" autoplay playsinline controls style="width: 100%; max-width: 600px; background-color: black;"></video>
    </div>

    <!-- 回放区域 -->
    <div style="flex: 2;">
        <h3>录像回放</h3>
        <!-- 日期选择 -->
        <div>
            <label for="date">选择日期</label>
            <input type="date" id="date" value="2025-07-23">
        </div>

        <!-- 开始时间 -->
        <div>
            <label for="startTime">开始时间</label>
            <input type="datetime-local" id="startTime">
        </div>

        <!-- 结束时间 -->
        <div>
            <label for="endTime">结束时间</label>
            <input type="datetime-local" id="endTime">
        </div>

        <!-- 按钮 -->
        <button onclick="playSelectedVideo()">播放选中时间段</button>

        <video id="recordVideo" class="video-js vjs-default-skin" controls style="width: 100%; max-width: 600px; hight: 100%;">
            <source id="recordSource" src="" type="video/mp4">
            您的浏览器不支持 video 标签。
        </video>

        <!-- 时间轴容器 -->
        <div id="timeline-container" style="margin-top: 20px; width: 100%; height: 30px; background-color: #f0f0f0; position: relative; overflow-x: auto;"></div>

    </div>
</div>


<!--<video controls autoplay>-->
<!--    <source src="flv://192.168.0.198:8180/live/camera_001.live.flv" type="video/x-flv">-->
<!--    您的浏览器不支持 video 标签。-->
<!--</video>-->

<script>

    window.onload = function () {
        const today = new Date();
        const dateInput = document.getElementById('date');
        const startDateInput = document.getElementById('startTime');
        const endDateInput = document.getElementById('endTime');

        // 设置默认日期（格式：YYYY-MM-DD）
        const year = today.getFullYear();
        const month = String(today.getMonth() + 1).padStart(2, '0');
        const day = String(today.getDate()).padStart(2, '0');
        dateInput.value = `${year}-${month}-${day}`;

        // 默认开始时间为当天 00:00
        startDateInput.value = `${year}-${month}-${day}T00:00`;

        // 默认结束时间为当天 23:59
        endDateInput.value = `${year}-${month}-${day}T23:59`;
    };

    // const serverUrl = "http://192.168.0.239:8180"; // 替换为你的本地服务地址
    const baseserverUrl = "http://192.168.0.198:8280"; // 替换为你的本地服务地址
    // const serverUrl = "http://192.168.0.239:8899"; // 替换为你的本地服务地址
    const serverUrl = "https://media.shenglong.com"; // 替换为你的本地服务地址
    let pc = null;

    var myHeaders = new Headers();
    myHeaders.append("secret", "035c73f7-bb6b-4889-a715-d9eb2d1925cc");
    myHeaders.append("User-Agent", "Apifox/1.0.0 (https://apifox.com)");
    myHeaders.append("Accept", "*/*");
    myHeaders.append("Host", serverUrl);
    myHeaders.append("Connection", "keep-alive");
    myHeaders.append("Origin", serverUrl); // 添加 origin
    myHeaders.append("Referer", serverUrl); // 添加 referer


    var requestOptions = {
        method: 'GET',
        headers: myHeaders,
        mode: 'cors', // 显式声明使用 CORS
        credentials: 'same-origin', // 如果需要携带 Cookie 可以设为 include
        redirect: 'follow'
    };
    async function generateOffer() {
        console.log("【DEBUG】generateOffer 开始");

        const app = document.getElementById('app').value.trim();
        const stream = document.getElementById('stream').value.trim();
        const type = document.getElementById('type').value.trim();
        const pcSdpInput = document.getElementById('pcSdp');
        const videoElement = document.getElementById('videoElement');

        pc = new RTCPeerConnection();

        // 添加调试日志
        pc.onicecandidate = async (event) => {
            console.log("【ICE Candidate】新候选地址:", event.candidate);
            if (event.candidate) {
                // 构造请求头，避免使用多个 Content-Type
                const headers = new Headers();
                headers.append("secret", "035c73f7-bb6b-4889-a715-d9eb2d1925cc");
                headers.append("Origin", serverUrl);
                headers.append("Referer", serverUrl);
                headers.append("Content-Type", "application/json");  // 使用 text/plain 避免 MIME 错误

                // 将 candidate 发送到信令服务器
                fetch(`${serverUrl}/index/api/webrtc_ice`, {
                    method: 'POST',
                    headers: headers,
                    body: JSON.stringify(event.candidate)
                });
            }
        };

        pc.ontrack = (event) => {
            console.log("【Track】收到远程流");
            if (!videoElement.srcObject) {
                videoElement.srcObject = event.streams[0];
            }
        };

        pc.onconnectionstatechange = () => {
            console.log("【连接状态变化】", pc.connectionState);
        };

        // 添加音视频收发器
        pc.addTransceiver("video", {direction: 'recvonly'});
        pc.addTransceiver("audio", {direction: 'recvonly'});

        try {
            // 创建 Offer
            const offer = await pc.createOffer();
            console.log("✅ 成功创建 Offer SDP");

            // 设置本地描述
            await pc.setLocalDescription(offer);
            console.log("📌 已设置 localDescription");

            const response = await fetch(`${serverUrl}/index/api/webrtc?app=${encodeURIComponent(app)}&stream=${encodeURIComponent(stream)}&type=play`, {
                method: 'POST',
                headers: {

                    'Content-Type': 'text/plain;charset=UTF-8',
                    'secret': '035c73f7-bb6b-4889-a715-d9eb2d1925cc',
                    'Origin': serverUrl,
                    'Referer': serverUrl
                },
                body: pc.localDescription.sdp
            });

            const data = await response.json();  // 解析为 JSON
            console.log("📨 接口响应数据:", data);

            if (data.code === 0 && data.sdp) {
                const answerDesc = new RTCSessionDescription({
                    type: 'answer',
                    sdp: data.sdp  // 使用返回的 SDP 构造 Answer
                });

                await pc.setRemoteDescription(answerDesc);
                console.log("✅ 成功设置 remoteDescription");
            } else {
                alert("❌ 获取 Answer SDP 失败：" + (data.message || data.data));
            }
        } catch (error) {
            console.error("⚠️ 发生错误:", error);
            alert("发生错误：" + error.message);
        }
    }



    // 新增函数：关闭播放
    function stopPlayback() {
        console.log("【关闭播放】开始");

        if (pc) {
            pc.close();
            pc = null;
        }

        const videoElement = document.getElementById('videoElement');
        if (videoElement.srcObject) {
            videoElement.srcObject = null;
        }

        alert("✅ 播放已关闭");
    }
    async function testBackend() {

        myHeaders.append("Content-Type", "application/json");
        const url = `${serverUrl}/index/api/getMediaList?app=live&schema=rtsp&stream=camera_001&secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc`;
        try {
            const res = await fetch(url, requestOptions);
            const data = await res.json();
            console.log("🔗 后端接口返回:", data);
            alert("✅ 后端接口可访问");
        } catch (e) {
            console.error("❌ 连接失败:", e);
            alert("❌ 后端接口不可访问，请检查服务是否运行");
        }
    }


    let videoUrls = []; // 从接口获取的视频 URL 列表

    async function playRecordedVideo() {
        const stream = document.getElementById('stream').value;
        const date = document.getElementById('date').value;

        const response = await fetch(`${baseserverUrl}/supply/media/api/video/fragments?cameraId=${stream}&date=${date}`);
        videoUrls = await response.json();

        if (videoUrls.length === 0) {
            alert("未找到对应日期的录像");
            return;
        }

        // 默认播放第一个
        // const recordVideo = document.getElementById('recordVideo');
        // const recordSource = document.getElementById('recordSource');
        // recordSource.src = videoUrls[0];
        // recordVideo.load();
        // recordVideo.play();
    }

    function playSelectedVideo() {
        playRecordedVideo()
        const selectedDate = document.getElementById('date').value;
        const startTime = document.getElementById('startTime').value;
        const endTime = document.getElementById('endTime').value;

        if (!startTime || !endTime) {
            alert("请选择开始和结束时间");
            return;
        }

        const start = new Date(startTime).getTime() / 1000;
        const end = new Date(endTime).getTime() / 1000;

        const matchedVideos = videoUrls.filter(url => {
            const fileName = url.split('/').pop();
            const parts = fileName.split('-');

            // 提取日期和时间部分
            const fileDate = `${parts[0]}-${parts[1]}-${parts[2]}`;
            const fileTimeStr = `${parts[3]}:${parts[4]}:${parts[5]}`;
            const fileDateTimeStr = `${fileDate}T${parts[3]}:${parts[4]}:${parts[5]}`;
            const fileTime = new Date(fileDateTimeStr).getTime() / 1000;

            return fileTime >= start && fileTime <= end;
        });

        if (matchedVideos.length === 0) {
            alert("未找到匹配的录像");
            return;
        }

        // 生成时间轴
        generateTimeline(matchedVideos);

        // 默认播放第一个
        playVideo(matchedVideos[0]);
    }

    function generateTimeline(videoList) {
        const container = document.getElementById('timeline-container');
        container.innerHTML = ""; // 清空旧内容

        if (videoList.length === 0) return;

        // 获取容器总宽度
        const containerWidth = container.clientWidth;

        // 提取最早和最晚时间，用于比例计算
        const times = videoList.map(url => {
            const fileName = url.split('/').pop();
            const parts = fileName.split('-');
            const timeStr = `${parts[3]}:${parts[4]}:${parts[5]}`;
            const dateStr = `${parts[0]}-${parts[1]}-${parts[2]}T${timeStr}`;
            return {
                url,
                startTime: new Date(dateStr).getTime() / 1000,
                endTime: new Date(dateStr).getTime() / 1000 + 10, // 每个视频 10 秒
            };
        });

        const minTime = Math.min(...times.map(t => t.startTime));
        const maxTime = Math.max(...times.map(t => t.endTime));
        const totalDuration = maxTime - minTime;

        times.forEach(item => {
            const startOffset = ((item.startTime - minTime) / totalDuration) * 100;
            const duration = ((item.endTime - item.startTime) / totalDuration) * 100;

            const segment = document.createElement('div');
            segment.className = 'timeline-segment';
            segment.style.left = `${startOffset}%`;
            segment.style.width = `${duration}%`;
            segment.style.backgroundColor = getRandomColor(); // 随机颜色区分片段
            segment.title = `时间：${formatTime(item.startTime)}`;

            segment.onclick = () => playVideo(item.url);

            container.appendChild(segment);
        });
    }

    function formatTime(seconds) {
        const date = new Date(seconds * 1000);
        return date.toTimeString().split(' ')[0];
    }

    function getRandomColor() {
        const letters = '6789ABCDEF'.split('');
        let color = '#';
        for (let i = 0; i < 6; i++) {
            color += letters[Math.floor(Math.random() * 10)];
        }
        return color;
    }


    function playVideo(url) {
        const recordVideo = document.getElementById('recordVideo');
        const recordSource = document.getElementById('recordSource');
        recordSource.src = url;
        recordVideo.load();
        recordVideo.play();
    }



</script>
<script src="https://vjs.zencdn.net/7.20.1/video.min.js"></script>
<link href="https://vjs.zencdn.net/7.20.1/video-js.css" rel="stylesheet">

</body>
</html>
<style>
    .timeline-segment {
        position: absolute;
        height: 100%;
        background-color: #007bff;
        border: 1px solid #0056b3;
        border-radius: 4px;
        cursor: pointer;
        color: white;
        font-size: 12px;
        display: flex;
        align-items: center;
        justify-content: center;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
</style>
